package com.house365.core.http;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.NameValuePair;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.message.AbstractHttpMessage;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

import android.content.Context;

import com.house365.core.application.BaseApplication;
import com.house365.core.bean.VersionInfo;
import com.house365.core.http.exception.HtppApiException;
import com.house365.core.http.exception.HttpParseException;
import com.house365.core.http.exception.NetworkUnavailableException;
import com.house365.core.json.JSONArray;
import com.house365.core.json.JSONException;
import com.house365.core.json.JSONObject;
import com.house365.core.reflect.ReflectException;
import com.house365.core.reflect.ReflectUtil;
import com.house365.core.util.DeviceUtil;

/**
 * @author py
 * @date 2012-6-28
 * @comment
 */
public abstract class HttpAPIAdapter extends BaseHttpAPI {
	private Context context;
	public HttpAPIAdapter(Context context) {
		this.context = context;
	}

	@Override
	protected void setDeaultRequestHeader(AbstractHttpMessage request) {
		// TODO Auto-generated method stub
		super.setDeaultRequestHeader(request);
		//加密
		request.addHeader("d", ((BaseApplication)(context)).getDigest());
	}
	@Override
	public int setConnectTimeOut() {
		return 30000;
	}

	@Override
	public String setCharEncode() {
		return HTTP.UTF_8;
	}

	@Override
	public boolean setUSEGIZP() {
		return true;
	}

	@Override
	public int setHttpPort() {
		return 80;
	}

	@Override
	public int setHttpsPort() {
		return 443;
	}

	public void setEncode(String encode) {
		CHARENCODE = encode;
	}

	public abstract VersionInfo getAppNewVersion();

	/***
	 * post请求，返回泛型对象
	 * 
	 * @param method
	 * @param params
	 * @param backobj
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 * @throws HttpParseException
	 */
	public <T> T postWithObject(String url, List<NameValuePair> list, T t)
			throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			result = post(url, list);

		} catch (Exception e) {
			throw new HtppApiException("postWithObject occurs exception", e);
		}
		try {
			return (T) ReflectUtil.copy(t.getClass(), new JSONObject(result));
		} catch (Exception e) {
			throw new HttpParseException("data parese  occurs exception:"
					+ result, e);
		}

	}

	/**
	 * post请求，返回泛型对象
	 * 
	 * @param url
	 * @param entity
	 * @param t
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 * @throws HttpParseException
	 */
	public <T> T postWithObject(String url, MultipartEntity entity, T t)
			throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			result = post(url, entity);
		} catch (Exception e) {
			throw new HtppApiException("postWithObject occurs exception", e);
		}
		try {
			return (T) ReflectUtil.copy(t.getClass(), new JSONObject(result));
		} catch (Exception e) {
			throw new HttpParseException("data parese  occurs exception:"
					+ result, e);
		}

	}

	/**
	 * post请求，返回泛型对象
	 * 
	 * @param url
	 * @param params
	 * @param t
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 * @throws HttpParseException
	 */
	public <T> T postWithObject(String url, Map<String, String> params, T t)
			throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			List<NameValuePair> list = new ArrayList<NameValuePair>();
			for (Map.Entry<String, String> entry : params.entrySet()) {
				list.add(new BasicNameValuePair(entry.getKey().toString(),
						entry.getValue().toString()));
			}
			result = post(url, list);
		} catch (Exception e) {
			throw new HtppApiException("postWithObject occurs exception", e);
		}
		try {
			return (T) ReflectUtil.copy(t.getClass(), new JSONObject(result));
		} catch (Exception e) {
			throw new HttpParseException("data parese  occurs exception:"
					+ result, e);
		}
	}

	/***
	 * post请求，返回泛型对象数组
	 * 
	 * @param method
	 * @param params
	 * @param backobj
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 * @throws HttpParseException
	 */
	public <T> List<T> postWithList(String url, List<NameValuePair> list, T t)
			throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			result = post(url, list);
		} catch (Exception e) {
			throw new HtppApiException("getWithList occurs exception", e);
		}
		try {
			List<T> ts = new ArrayList<T>();
			JSONArray aJsonArray = null;
			aJsonArray = new JSONArray(result);
			if (aJsonArray != null) {
				T n;
				for (int i = 0; i < aJsonArray.length(); i++) {
					n = (T) ReflectUtil.copy(t.getClass(),
							aJsonArray.getJSONObject(i));
					ts.add(n);
				}
			}

			return ts;
		} catch (Exception e) {
			throw new HttpParseException("data parese  occurs exception:"
					+ result, e);
		}
	}

	/**
	 * 
	 * @param url
	 * @param entity
	 * @param t
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 * @throws HttpParseException
	 */
	public <T> List<T> postWithList(String url, MultipartEntity entity, T t)
			throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			result = post(url, entity);

		} catch (Exception e) {
			throw new HtppApiException("postWithObject occurs exception", e);
		}
		try {
			List<T> ts = new ArrayList<T>();
			JSONArray aJsonArray = null;
			aJsonArray = new JSONArray(result);
			if (aJsonArray != null) {
				T n;
				for (int i = 0; i < aJsonArray.length(); i++) {
					n = (T) ReflectUtil.copy(t.getClass(),
							aJsonArray.getJSONObject(i));
					ts.add(n);
				}
			}

			return ts;
		} catch (Exception e) {
			throw new HttpParseException("data parese  occurs exception:"
					+ result, e);
		}
	}

	/**
	 * get请求，返回字符串
	 * 
	 * @param url
	 * @param params
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 */
	public String getWithString(String url, Map<String, String> params)
			throws HtppApiException, NetworkUnavailableException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		try {
			List<NameValuePair> list = new ArrayList<NameValuePair>();
			for (Map.Entry<String, String> entry : params.entrySet()) {
				list.add(new BasicNameValuePair(entry.getKey().toString(),
						entry.getValue().toString()));
			}
			String result = get(url, list);
			return result;
		} catch (Exception e) {
			throw new HtppApiException("getWithObject occurs exception", e);
		}
	}

	/**
	 * get请求，返回字符串,自定义超时时间
	 * 
	 * @param url
	 * @param params
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 */
	public String getWithString(String url, Map<String, String> params,
			int timeout) throws HtppApiException, NetworkUnavailableException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		try {
			List<NameValuePair> list = new ArrayList<NameValuePair>();
			for (Map.Entry<String, String> entry : params.entrySet()) {
				list.add(new BasicNameValuePair(entry.getKey().toString(),
						entry.getValue().toString()));
			}
			String result = get(url, list, timeout);
			return result;
		} catch (Exception e) {
			throw new HtppApiException("getWithObject occurs exception", e);
		}
	}
	/**
	 * get请求，返回字符串
	 * 
	 * @param url
	 * @param params
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 */
	public String getWithString(String url, List<NameValuePair> list)
			throws HtppApiException, NetworkUnavailableException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		try {
			String result = get(url, list);
			return result;
		} catch (Exception e) {
			throw new HtppApiException("getWithObject occurs exception", e);
		}
	}

	/**
	 * get请求，返回字符串,自定义超时时间
	 * 
	 * @param url
	 * @param params
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 */
	public String getWithString(String url, List<NameValuePair> list,
			int timeout) throws HtppApiException, NetworkUnavailableException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		try {
			String result = get(url, list, timeout);
			return result;
		} catch (Exception e) {
			throw new HtppApiException("getWithObject occurs exception", e);
		}
	}

	/**
	 * get请求，返回泛型对象,自定义超时时间
	 * 
	 * @param url
	 * @param list
	 * @param t
	 * @param timeout
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 * @throws HttpParseException
	 */
	public <T> T getWithObject(String url, List<NameValuePair> list, T t,
			int timeout) throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			result = get(url, list, timeout);

		} catch (Exception e) {
			throw new HtppApiException("getWithObject occurs exception", e);
		}
        try {
            return (T) ReflectUtil.copy(t.getClass(), new JSONObject(result));
        } catch (Exception e) {
            e.printStackTrace();
            throw new HttpParseException("data parese  occurs exception:", e);
        }
	}

	/**
	 * get请求，返回泛型对象
	 * 
	 * @param url
	 * @param list
	 * @param t
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 * @throws HttpParseException
	 */
	public <T> T getWithObject(String url, List<NameValuePair> list, T t)
			throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			result = get(url, list);

		} catch (Exception e) {
			throw new HtppApiException("getWithObject occurs exception", e);
		}
        try {
            return (T) ReflectUtil.copy(t.getClass(), new JSONObject(result));
        } catch (Exception e) {
            e.printStackTrace();
            throw new HttpParseException("data parese  occurs exception:", e);
        }

	}

	/**
	 * get请求，返回泛型对象
	 * 
	 * @param url
	 * @param params
	 * @param t
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 * @throws HttpParseException
	 */
	public <T> T getWithObject(String url, Map<String, String> params, T t)
			throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			List<NameValuePair> list = new ArrayList<NameValuePair>();
			for (Map.Entry<String, String> entry : params.entrySet()) {
				list.add(new BasicNameValuePair(entry.getKey().toString(),
						entry.getValue().toString()));
			}
			result = get(url, list);

		} catch (Exception e) {
			throw new HtppApiException("getWithObject occurs exception", e);
		}
		try {
			return (T) ReflectUtil.copy(t.getClass(), new JSONObject(result));
		} catch (Exception e) {
			throw new HttpParseException("data parese  occurs exception:"
					+ result, e);
		}
	}

	/***
	 * get请求，最终返回list对象
	 * 
	 * @param method
	 * @param params
	 * @param backobj
	 * @return
	 * @throws HtppApiException
	 * @throws NetworkUnavailableException
	 * @throws HttpParseException
	 */
	public <T> List<T> getWithList(String url, List<NameValuePair> list, T t)
			throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			result = get(url, list);

		} catch (Exception e) {
			throw new HtppApiException("getWithList occurs exception", e);
		}
		try {
			List<T> ts = new ArrayList<T>();
			JSONArray aJsonArray = null;
			aJsonArray = new JSONArray(result);
			if (aJsonArray != null) {
				T n;
				for (int i = 0; i < aJsonArray.length(); i++) {
					n = (T) ReflectUtil.copy(t.getClass(),
							aJsonArray.getJSONObject(i));
					ts.add(n);
				}
			}

			return ts;
		} catch (Exception e) {
			throw new HttpParseException("data parese  occurs exception:"
					+ result, e);
		}
	}

	/**
	 * 私有方法，将string对应的Json数组转换成泛型List
	 * 
	 * @param str
	 * @param t
	 * @return
	 * @throws HtppApiException
	 */
	public <T> List<T> getListWithString(String str, T t)
			throws HttpParseException {
		try {
			JSONArray aJsonArray = null;
			aJsonArray = new JSONArray(str);
			List<T> ts = new ArrayList<T>();
			if (aJsonArray != null) {
				T n;
				for (int i = 0; i < aJsonArray.length(); i++) {
					n = (T) ReflectUtil.copy(t.getClass(),
							aJsonArray.getJSONObject(i));
					ts.add(n);
				}
			}
			return ts;
		} catch (Exception e) {
			throw new HttpParseException(
					"data parese  occurs exception:" + str, e);
		}
	}

	public <T> List<T> getWithList(String url, Map<String, String> params, T t)
			throws HtppApiException, NetworkUnavailableException,
			HttpParseException {
		if (!DeviceUtil.isNetConnect(context)) {
			throw new NetworkUnavailableException("Network Unavailable.");
		}
		String result = null;
		try {
			List<NameValuePair> list = new ArrayList<NameValuePair>();
			for (Map.Entry<String, String> entry : params.entrySet()) {
				list.add(new BasicNameValuePair(entry.getKey().toString(),
						entry.getValue().toString()));
			}
			result = get(url, list);

		} catch (Exception e) {
			throw new HtppApiException("getWithList occurs exception", e);
		}
		try {
			List<T> ts = new ArrayList<T>();
			JSONArray aJsonArray = null;
			aJsonArray = new JSONArray(result);
			if (aJsonArray != null) {
				T n;
				for (int i = 0; i < aJsonArray.length(); i++) {
					n = (T) ReflectUtil.copy(t.getClass(),
							aJsonArray.getJSONObject(i));
					ts.add(n);
				}
			}

			return ts;
		} catch (Exception e) {
			throw new HttpParseException("data parese  occurs exception:"
					+ result, e);
		}
	}

}